package com.lw.leetcode.linked.c;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * c
 * link
 * https://leetcode.cn/contest/cnunionpay2022/problems/NyZD2B/
 * 银联-4. 设计自动售货机
 *
 * @author liw
 * @version 1.0
 * @date 2023/2/16 16:24
 */
public class VendingMachine {

    public static void main(String[] args) {
        VendingMachine test = new VendingMachine();

        // [null,null,10,-1,-1,-1]
//        test.addItem(0,3,"Apple",10,10);
//        System.out.println(test.sell(1,"Tom","Apple",1));
//        System.out.println(test.sell(2, "Tom", "Apple", 3));
//        System.out.println(test.sell(3, "Mary", "Banana", 2));
//        System.out.println(test.sell(11, "Jim", "Apple", 1));

        // [null,null,null,8]
//        test.addItem(0, 1, "Apple", 4, 3);
//        test.addItem(1, 3, "Apple", 4, 2);
//        System.out.println(test.sell(2, "Mary", "Apple", 2));
    }

    private Node st;
    private Node end;
    private Map<String, LinkedList<Node>> map;
    private Map<String, Integer> customers;

    public VendingMachine() {
        this.st = new Node("", 0, 0, 0);
        this.end = new Node("", 0, 0, Integer.MAX_VALUE);
        this.map = new LinkedHashMap<>();
        this.customers = new HashMap<>();
        st.next = end;
        end.pre = st;
    }

    public void addItem(int time, int number, String item, int price, int duration) {
        int out = time + duration;
        Node node = new Node(item, number, price, out);

        Node no = st;
        while (out > no.next.out) {
            no = no.next;
        }

        Node next = no.next;

        no.next = node;
        node.pre = no;
        node.next = next;
        next.pre = node;
        map.computeIfAbsent(item, v -> new LinkedList<>()).add(node);
    }

    public long sell(int time, String customer, String item, int number) {
        while (st.next.out < time) {
            Node next = st.next;
            map.get(next.item).remove(next);
            st.next = st.next.next;
        }
        LinkedList<Node> nodes = map.get(item);
        if (nodes == null || nodes.isEmpty()) {
            return -1;
        }
        long sum = 0;
        for (Node node : nodes) {
            sum += node.num;
        }
        if (sum < number) {
            return -1;
        }
        int p = customers.getOrDefault(customer, 100);
        List<Node> list = new ArrayList<>(nodes);
        list.sort((a, b) -> a.price == b.price ? Integer.compare(a.out, b.out) : Integer.compare(a.price, b.price));
        long all = 0;
        for (Node node : list) {
            if (number - node.num < 0) {
                all += (long) node.price * number;
                node.num = node.num - number;
                break;
            } else {
                all += (long) node.price * node.num;
                nodes.remove(node);
                Node pre = node.pre;
                Node next = node.next;
                pre.next = next;
                next.pre = pre;
                number -= node.num;
            }
        }
        all = (all * p + 99) / 100;
        customers.put(customer, (p - 1) < 70 ? 70 : (p - 1));
        return all;
    }

    private class Node {
        private String item;
        private int num;
        private int price;
        private int out;
        private Node pre;
        private Node next;

        public Node(String item, int num, int price, int out) {
            this.item = item;
            this.num = num;
            this.price = price;
            this.out = out;
        }
    }

}
